/*
    Author: Christopher Diggins
    License: MIT Licence 1.0
    Website: http://www.cdiggins.com
*/

#ifndef CVML_CAT_PARSER_HPP
#define CVML_CAT_PARSER_HPP

// Not currently implemented. 
// This uses the old "ByteStream" class which is no longer in use

/*
struct CatParser 
{
	typedef const char* Iterator;
	typedef char Token;

	ByteStream* stream;
	std::string capture;
	bool isCapturing;

	CatParser(ByteStream* output)
		: begin(NULL), end(NULL), stream(output), isCapturing(false)
	{ }

	template<typename Rule_T>
	bool Parse(const char* input)
	{
		try {
			begin = input;
			cur = begin;
			end = input + strlen(input);
			return typename Rule_T::Match(*this);
		}
		catch(...) {
			return false;
		}
	}

	/// Performs a match and stores a string in the variable 'capture'
	/// that corresponds to the match. Calls to Capture cannot be nested. 
	template<typename T>
	bool Capture(const T& x)
	{ 
		Assert(!isCapturing);
		isCapturing = true;
		Iterator i = cur;
		bool r = T::Match(*this);
		isCapturing = false;	
		if (r) {
			capture = std::string(i, cur);
		}
		return r;
	};

	bool Store(const shared_grammar::BinNumber& x)
	{ 
		if (!Capture(x)) return false;
		// TODO: add a new binary number to the stream.
		return true;
	};

	bool Store(const shared_grammar::DecNumber& x)
	{ 
		if (!Capture(x)) return false;
		stream->AddInt(StrToInt(capture));
		return true;
	};

	bool Store(const shared_grammar::HexNumber& x)
	{ 
		if (!Capture(x)) return false;
		stream->AddInt(HexStrToInt(capture));
		return true;
	};

	bool Store(const shared_grammar::CharLiteral& x)
	{ 
		if (!Capture(x)) return false;
		Error("unimplemented");
		return true;
	};

	bool Store(const shared_grammar::StringLiteral& x) 
	{ 
		if (!Capture(x)) return false;
		Error("unimplemented");
		return true;
	};

	bool Store(const cat_grammar::QuotedExpr& x)
	{
		stream->BeginQuotation();
		bool r = x.Match(*this);
		stream->EndQuotation();		
		return r;
	}

	bool Store(const cat_grammar::Arg& x)
	{	
		if (!Capture(x)) return false;
		stream->AddDefn(capture);
		return true;
	};

	bool Store(const cat_grammar::Operation& x)
	{ 
		if (!Capture(x)) return false;
		OpCodeEnum code = StrToOpCode(capture);
		if (GetOpCodeWidth(code) > 1)
			Error("Wide op-codes not supported yet");
		stream->AddInstruction(code);
		return true;
	};
	
	bool Store(const cat_grammar::LocalDef& x) 
	{
		// TODO: finish. 
		// I have lost track of how this should actually work.
		// I think I would need to update how bytestream works
		// so that it knows what are vars and what are defs.
		return x.Match(*this);
	}

	bool Store(const cat_grammar::DefBody& x)
	{ 
		std::string name = capture;
		stream->BeginFunction(name);
		bool r = x.Match(*this);
		stream->EndFunction();
		return r;
	}

	bool Store(const cat_grammar::DefName& x)
	{
		return Capture(x);
	}

    template<typename Rule_T>
    bool Store() 
	{ 
		return Store(Rule_T());
	}
            
    Token GetElem() { return *cur; } 
    void GotoNext() { assert(GetPos() < End()); ++cur; }  
    Iterator GetPos() { return cur; }  
    void SetPos(Iterator pos) { cur = pos; }  
    bool AtEnd() { return GetPos() >= End(); }  
    Iterator Begin() { return begin; }    
    Iterator End() { return end; }  

    void OutputLocation()
    {
        char line[256];
        Iterator pFirst = GetPos();
        while (pFirst > Begin() && *pFirst != '\n')
            pFirst--;
        if (*pFirst == '\n')
            ++pFirst;
        Iterator pLast = GetPos();
        while (pLast < End() && *pLast != '\n')
            pLast++;
        size_t n = pLast - pFirst;
        n = n < 254 ? n : 254;
        strncpy(line, pFirst, n);    
        line[n] = '\0';

        char marker[256];
        n = GetPos() - pFirst;
        n = n < 254 ? n : 254;
        for (size_t i=0; i < n; ++i)
            marker[i] = ' ';
        marker[n] = '^';
        marker[n + 1] = '\0';

        // Count lines  
        int nline = 1;
        for (Iterator p = Begin(); p < pFirst; ++p) {
            if (*p == '\n') {
                ++nline;
            }
        }

        printf("character number %d\n", n); 
        printf("line number %d\n", nline);
        printf("%s\n", line); 
        printf("%s\n", marker);
    }

private:

	Iterator begin;
	Iterator end;
	Iterator cur;
};

bool ParseCatProgram(const char* input, ByteStream* stream)
{
	CatParser parser(stream);
	return parser.Parse<cat_grammar::Program>(input);
}

bool ParseCatExpression(const char* input, ByteStream* stream)
{
	CatParser parser(stream);
	return parser.Parse<cat_grammar::Expr>(input);
};
*/

#endif 
